<?php
/**
 * 创客复销服务类，主要功能，检查复销日期是否过期，及业绩加扣相关的业务
 * @author liujun
 */
namespace App\System\Cis\Services;

use App\Jobs\SendMsg;
use App\System\Base\Repositories\BaseSettingRepository;
use App\System\Cis\Repositories\CisUserRepository;
use App\System\Log\Repositories\LogSmsRepository;
use Illuminate\Support\Facades\DB;

class RepeatedEliminationService
{
    /**
     * 错误信息
     * @var
     */
    private $errorMsg;

    /**
     * 用户模型对像
     * @var
     */
    private $userObj;

    /**
     * 短信记录模型对像
     * @var
     */
    private $logSms;

    /**
     * 所有用上级用户数据
     * @var
     */
    private $superiorUserData;

    /**
     * @var
     * 要发送的短信数组
     */
    private $smsData;

    /**
     * 设置数组
     * @var
     */
    private $setting;

    public function __construct()
    {
        $this->getSetting();
        $this->userObj = CisUserRepository::getInstance();
        $this->logSms = LogSmsRepository::getInstance();
    }

    /**
     * 每日执行计划任务
     *
     */
    public function findAllTheUsersToSend()
    {
        //DB::beginTransaction();
        $this->findThreeDays();
        //$this->findEightySevenDay();
        //$this->findOverdueOneDay();
       // $this->findNinetyOneDaysExpired();
        //DB::commit();
        $this->sendMsg();//执行发送短信队列
    }

    /**
     * 查询3天后就要过复销期的用户
     */
    private function findThreeDays()
    {
        $data = $this->userObj->findRepeatedElimination(1);
        $this->dataCycleProcessing($data,1);

    }

    /**
     * 查询过期87天的用户
     */
    private function findEightySevenDay()
    {
        $data = $this->userObj->findRepeatedElimination(2);
        $this->dataCycleProcessing($data,5);
    }

    /**
     * 查询过期一天的用户
     */
    private function findOverdueOneDay()
    {
        $data = $this->userObj->findRepeatedElimination(3);
        $this->dataCycleProcessing($data,3);
    }

    /**
     * 查询过期91天的用户
     */
    private function findNinetyOneDaysExpired()
    {
        $data = $this->userObj->findRepeatedElimination(4);
        $this->dataCycleProcessing($data,7);
    }

    /**
     * 复销用户数据循环处理
     * @param $data object 要循环的数据
     * @param $type 类型 1复销前3天 3过了复消期1天 5过了复消期87-90天 7过了复销期90天
     */
    private function dataCycleProcessing($data,$msgtype=0)
    {
        foreach ($data as $v)
        {
            if($msgtype < 6)
            {//执行发短信提示操作
                $m_data = $this->setSmsTemplate($v,$msgtype);
                $this->generateMessageRecord($v->mobile,$msgtype,0,$m_data);//发送给当前用户
                if($v['superior_maker_ids'])
                {
                    $ids = explode(",",$v['superior_maker_ids']);
                    $list = $this->userObj->getPaycheckUserByIds($ids);
                    $i =1;
                    foreach ($list as $val)
                    {
                        if($i>2) continue;//只发送给前两个发工资的用户
                        $m_data = $this->setSmsTemplate($v,$msgtype+1);
                        $this->generateMessageRecord($val['mobile'],$msgtype+1,0,$m_data);
                        $i++;
                    }
                }
                if($msgtype == 3)
                {//过了复销期需要扣减业绩
                    $achievement = $this->matchedWageCoefficient($v);
                    $this->externalUpdatePerformanceInterface($v['superior_maker_ids'],$v['id'],2,$achievement);//扣减上级的业绩
                }
            }
            elseif($msgtype ==7)
            {//执行账号停用操作
                $this->userObj->updateUser(['status'=>3],$v['id']);
            }
        }
    }

    /**
     * 设置模板参数
     * @param $data 用户数组
     * @param $type 模板ID
     */
    private function setSmsTemplate($data,$type)
    {
        switch ($type)
        {
            case 1:
                $data = [date("m月d日",strtotime($data['repeated_consumption_date']))];
                break;
            case 2:
                $data = [date("m月d日",strtotime($data['repeated_consumption_date'])),$data['id']];
                break;
            case 3:
                $data = [];
                break;
            case 4:
                $data = [$data['id']];
                break;
            case 5:
                $data = [date("m月d日",strtotime($data['repeated_consumption_date']))];
                break;
            case 6:
                $data = [$data['id'],date("m月d日",strtotime($data['repeated_consumption_date']))];
                break;
        }
        return $data;
    }

    /**
     * 更新上层用户数量,业绩
     * @param $user_ids 上层用户ID数组
     * @param $income 1增加 2减少
     * @param $achievement 要增加减少的业绩
     * @return boolean
     */
    private function updateStatisticalData($user_ids,$income=1,$achievement=0)
    {

        $user_market = [];
        foreach ($this->superiorUserData as $v)
        {
            //用当前用户的上级ID做KEY，当前用户的区域赋值，用于在后面进行业绩的更新
            if($v->superior_maker_id)
            {
                $user_market[$v->superior_maker_id] = $v->user_area;
            }
        }
        $achievement_array = [
                                1=>'entrepreneurship_achievement',
                                2=>'chuangheng_achievement',
                                3=>'director_achievement'
                             ];
        //1更新上层用户数量,业绩
        $user_ids = explode(",",$user_ids);
        foreach ($user_ids as $v)
        {
            if($v > 1)
            {
                $update = $this->userObj->updateUserManyPurse($v,$income,['total_users_number'=>1,$achievement_array[$user_market[$v]]=>$achievement]);
                if(!$update)
                {
                    return $this->errorMsg = '更新用户数量，业绩出错';
                }
            }

        }

    }

    /**
     * 生成短信记录
     * @param $mobile 手机
     * @param $type 短信模板类型
     * @param array $user_id 用户ID
     * @param array $data 数据
     */
    private function generateMessageRecord($mobile,$type,$user_id=[],$data=[])
    {
        $this->smsData[] = ['mobile'=>$mobile,'type'=>$type,'user_id'=>$user_id,'data'=>$data];
    }

    /**
     * 发送短信
     */
    private function sendMsg()
    {
        if($this->smsData)
        {
            var_dump($this->smsData);
            foreach ($this->smsData as $v)
            {

                SendMsg::dispatch($v['mobile'],$v['type'],$v['data'],$v['user_id']);
            }

        }
    }

    /**
     * 获取错误信息
     * @return mixed
     */
    public function getErrorMsg()
    {
        return $this->errorMsg;
    }

    /**
     * 外部调用更新所有上级用户业绩入口
     * @param $user_ids array 当前用户所有上级用户ID数组
     * @param $user_id 当前用户ID
     * @param $income 1增加 2减少
     * @param $achievement 要增加减小的业绩
     * @return string
     */
    private function externalUpdatePerformanceInterface($user_ids,$user_id,$income,$achievement)
    {
        $user_ids_array  = explode(",",$user_ids);
        $user_ids_array[] = $user_id;
        $user = $this->userObj->getByInUser($user_ids_array);//查询所有上级用户包括自己的
        $this->superiorUserData = $user;
        $this->updateStatisticalData($user_ids,$income,$achievement);
        return $this->errorMsg;
    }

    /**
     * 获取设置信息,并组装格式
     * @return mixed
     */
    private function getSetting()
    {
        $setting_array = [];
        $setting = BaseSettingRepository::getInstance()->getSetting();
        $array_key = [1=>'y',2=>'x',3=>'d',4=>'g'];//y创业区业绩 x创新区业绩 d懂事区业绩 g日工资
        for ($i=0;$i<13;$i++)
        {
            $level_setting = [];
            if($i == 0)
            {
                $level_setting['y'] = 1000;
                $level_setting['x'] = 1000;
                $level_setting['d'] = 0;
                $level_setting['g'] = 35;
            }
            else
            {
                for ($j=1;$j<5;$j++)
                {
                    $level_setting[$array_key[$j]] = isset($setting[$i.$j]) ? $setting[$i.$j] : 0;
                }
            }

            $setting_array[$i] = $level_setting;
        }
        return $this->setting =$setting_array;
    }

    /**
     * 匹配工资系数
     * @param $user 用户信息数组
     */
    private function matchedWageCoefficient($user)
    {
        $setting_key = 0;
        foreach ($this->setting as $k => $v)
        {
            if($user['y'] >= $v['y'] && $user['x'] >= $v['x'] && $user['d'] >= $v['d'])
            {
                if($k > $setting_key)
                {//匹配大的就更新
                    $setting_key = $k;
                }
            }
        }
        $achievement = [0=>4000,1=>13000,2=>41000,3=>81000];//创客等级对应应扣的业绩匹配数组
        return $achievement[$setting_key];
    }
}